﻿package net.wangit.view.chart.impl;

import java.text.DecimalFormat;

import net.wangit.MapList;
import net.wangit.util.Checker;
import net.wangit.view.chart.util.DatasetUtil;

import org.jfree.chart.axis.CategoryAxis;
import org.jfree.chart.axis.CategoryAxis3D;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.axis.NumberAxis3D;
import org.jfree.chart.labels.ItemLabelAnchor;
import org.jfree.chart.labels.ItemLabelPosition;
import org.jfree.chart.labels.StandardCategoryItemLabelGenerator;
import org.jfree.chart.plot.CategoryPlot;
import org.jfree.chart.plot.Plot;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.renderer.category.AbstractCategoryItemRenderer;
import org.jfree.data.general.Dataset;
import org.jfree.ui.TextAnchor;


public abstract class CategoryChart extends AbstractChart {

	public CategoryChart() {
	}

	protected Plot getPlot() {
		CategoryPlot plot = getCategoryPlot();
		configCategoryPlot(plot);
		return plot;
	}

	private void configCategoryPlot(CategoryPlot plot) {
		plot.setOrientation(orientation);
		plot.setDomainGridlinesVisible(domainGridlinesVisible);
		if (domainGridlinesVisible) {
			if (domainGridlinesColor != null)
				plot.setDomainGridlinePaint(domainGridlinesColor);
			if (domainGridlinesStroke != null)
				plot.setDomainGridlineStroke(domainGridlinesStroke);
			plot.setDomainGridlinePosition(domainGridlinesPosition);
		}
		plot.setRangeGridlinesVisible(rangeGridlinesVisible);
		if (rangeGridlinesVisible) {
			if (rangeGridlinesColor != null)
				plot.setRangeGridlinePaint(rangeGridlinesColor);
			if (rangeGridlinesStroke != null)
				plot.setRangeGridlineStroke(rangeGridlinesStroke);
		}
		plot.setAxisOffset(axisOffset);
	}

	protected abstract CategoryPlot getCategoryPlot();

	protected CategoryAxis getCategoryAxis() {
		CategoryAxis axis = new CategoryAxis(categoryLabel);
		configCategoryAxis(axis);
		return axis;
	}

	protected NumberAxis getNumberAxis() {
		NumberAxis axis = new NumberAxis(valueLabel);
		configNumberAxis(axis);
		return axis;
	}

	protected CategoryAxis getCategoryAxis3D() {
		CategoryAxis axis = new CategoryAxis3D(categoryLabel);
		configCategoryAxis(axis);
		return axis;
	}

	protected NumberAxis getNumberAxis3D() {
		NumberAxis axis = new NumberAxis3D(valueLabel);
		configNumberAxis(axis);
		return axis;
	}

	private void configCategoryAxis(CategoryAxis axis) {
		axis.setVisible(categoryAxisVisible);
		if (categoryAxisLabelColor != null)
			axis.setLabelPaint(categoryAxisLabelColor);
		axis.setLabelFont(categoryAxisLabelFont);
		if (categoryAxisTickLabelColor != null)
			axis.setTickLabelPaint(categoryAxisTickLabelColor);
		axis.setTickLabelFont(categoryAxisTickLabelFont);
		axis.setCategoryLabelPositions(categoryAxisCategoryLabelPositions);
	}

	private void configNumberAxis(NumberAxis axis) {
		axis.setVisible(numberAxisVisible);
		if (numberAxisLabelColor != null)
			axis.setLabelPaint(numberAxisLabelColor);
		axis.setLabelFont(numberAxisLabelFont);
		if (numberAxisTickLabelColor != null)
			axis.setTickLabelPaint(numberAxisTickLabelColor);
		axis.setTickLabelFont(numberAxisTickLabelFont);
		axis.setUpperMargin(numberAxisUpperMargin);
		axis.setLowerMargin(numberAxisLowerMargin);
	}

	protected void configCategoryRenderer(AbstractCategoryItemRenderer renderer) {
		configRenderer(renderer);
		if (itemLabelsPosition == 3) {
			ItemLabelPosition position = new ItemLabelPosition(
					ItemLabelAnchor.CENTER, TextAnchor.CENTER);
			renderer.setPositiveItemLabelPosition(position);
			renderer.setNegativeItemLabelPosition(position);
		} else if (itemLabelsPosition == 2) {
			if (orientation == PlotOrientation.HORIZONTAL) {
				ItemLabelPosition position1 = new ItemLabelPosition(
						ItemLabelAnchor.OUTSIDE3, TextAnchor.CENTER_LEFT);
				renderer.setPositiveItemLabelPosition(position1);
				ItemLabelPosition position2 = new ItemLabelPosition(
						ItemLabelAnchor.OUTSIDE9, TextAnchor.CENTER_RIGHT);
				renderer.setNegativeItemLabelPosition(position2);
			} else if (orientation == PlotOrientation.VERTICAL) {
				ItemLabelPosition position1 = new ItemLabelPosition(
						ItemLabelAnchor.OUTSIDE12, TextAnchor.BOTTOM_CENTER);
				renderer.setPositiveItemLabelPosition(position1);
				ItemLabelPosition position2 = new ItemLabelPosition(
						ItemLabelAnchor.OUTSIDE6, TextAnchor.TOP_CENTER);
				renderer.setNegativeItemLabelPosition(position2);
			}
		} else {
			renderer.setPositiveItemLabelPosition(new ItemLabelPosition());
		}
		if (Checker.isEmpty(itemlabelFormat))
			renderer
					.setItemLabelGenerator(new StandardCategoryItemLabelGenerator());
		else
			renderer
					.setItemLabelGenerator(new StandardCategoryItemLabelGenerator(
							itemlabelFormat, new DecimalFormat()));
	}

	protected Dataset toDataset(MapList list) {
		return DatasetUtil.toCategoryDataset(list);
	}
}
